#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 包含数据结构定义
typedef struct {
    long id;
    char date[11];
    int type;
    char category[20];
    double amount;
    char note[50];
} FinanceRecord;

typedef FinanceRecord DataType;

// 单链表节点
typedef struct Node {
    DataType data;
    struct Node *next;
} SLNode;

// 声明链表函数
int ListLength(SLNode *head);
int ListInsert(SLNode *head, int i, DataType x);

// 生成唯一ID
long generateId() {
    return time(NULL) + rand();
}

// 验证日期格式
int isValidDate(const char *date) {
    if(strlen(date) != 10) return 0;
    if(date[4] != '-' || date[7] != '-') return 0;
    
    for(int i = 0; i < 10; i++) {
        if(i == 4 || i == 7) continue;
        if(date[i] < '0' || date[i] > '9') return 0;
    }
    
    return 1;
}

// 打印单条记录
void printRecord(FinanceRecord record) {
    printf("%ld\t%s\t%s\t%s\t%.2lf\t%s\n",
           record.id,
           record.date,
           record.type == 0 ? "收入" : "支出",  // 0=INCOME, 1=EXPENSE
           record.category,
           record.amount,
           record.note);
}

// 添加账务记录
void addRecord(SLNode *head) {
    FinanceRecord record;
    char typeInput[10];
    
    record.id = generateId();
    
    printf("请输入日期(YYYY-MM-DD): ");
    scanf("%s", record.date);
    if(!isValidDate(record.date)) {
        printf("日期格式错误！\n");
        return;
    }
    
    printf("请输入类型(income/expense): ");
    scanf("%s", typeInput);
    if(strcmp(typeInput, "income") == 0) {
        record.type = 0;  // INCOME
    } else if(strcmp(typeInput, "expense") == 0) {
        record.type = 1;  // EXPENSE
    } else {
        printf("类型输入错误！\n");
        return;
    }
    
    printf("请输入类别: ");
    scanf("%s", record.category);
    
    printf("请输入金额: ");
    scanf("%lf", &record.amount);
    
    printf("请输入备注: ");
    getchar();
    fgets(record.note, 50, stdin);
    record.note[strcspn(record.note, "\n")] = 0;
    
    int pos = ListLength(head);
    if(ListInsert(head, pos, record)) {
        printf("记录添加成功！ID: %ld\n", record.id);
    } else {
        printf("记录添加失败！\n");
    }
}

// 删除账务记录
void deleteRecord(SLNode *head) {
    long id;
    printf("请输入要删除的交易ID: ");
    scanf("%ld", &id);
    
    SLNode *p = head->next;
    SLNode *prev = head;
    
    while(p != NULL) {
        if(p->data.id == id) {
            FinanceRecord deletedRecord;
            prev->next = p->next;
            deletedRecord = p->data;
            free(p);
            
            printf("删除成功！删除的记录信息：\n");
            printRecord(deletedRecord);
            return;
        }
        prev = p;
        p = p->next;
    }
    
    printf("未找到ID为 %ld 的记录！\n", id);
}

// 修改账务记录
void modifyRecord(SLNode *head) {
    long id;
    printf("请输入要修改的交易ID: ");
    scanf("%ld", &id);
    
    SLNode *p = head->next;
    
    while(p != NULL) {
        if(p->data.id == id) {
            FinanceRecord *record = &(p->data);
            printf("找到记录，当前信息：\n");
            printRecord(*record);
            
            printf("请输入新日期(YYYY-MM-DD): ");
            scanf("%s", record->date);
            if(!isValidDate(record->date)) {
                printf("日期格式错误！\n");
                return;
            }
            
            char typeInput[10];
            printf("请输入新类型(income/expense): ");
            scanf("%s", typeInput);
            if(strcmp(typeInput, "income") == 0) {
                record->type = 0;
            } else if(strcmp(typeInput, "expense") == 0) {
                record->type = 1;
            } else {
                printf("类型输入错误！\n");
                return;
            }
            
            printf("请输入新类别: ");
            scanf("%s", record->category);
            
            printf("请输入新金额: ");
            scanf("%lf", &record->amount);
            
            printf("请输入新备注: ");
            getchar();
            fgets(record->note, 50, stdin);
            record->note[strcspn(record->note, "\n")] = 0;
            
            printf("修改成功！\n");
            return;
        }
        p = p->next;
    }
    
    printf("未找到ID为 %ld 的记录！\n", id);
}

// 按ID查询
void queryById(SLNode *head) {
    long id;
    printf("请输入交易ID: ");
    scanf("%ld", &id);
    
    SLNode *p = head->next;
    while(p != NULL) {
        if(p->data.id == id) {
            printf("查询结果：\n");
            printf("ID\t日期\t\t类型\t类别\t金额\t备注\n");
            printf("------------------------------------------------------------\n");
            printRecord(p->data);
            return;
        }
        p = p->next;
    }
    
    printf("未找到ID为 %ld 的记录！\n", id);
}

// 按类别查询
void queryByCategory(SLNode *head) {
    char category[20];
    printf("请输入类别: ");
    scanf("%s", category);
    
    SLNode *p = head->next;
    int found = 0;
    
    printf("查询结果：\n");
    printf("ID\t日期\t\t类型\t类别\t金额\t备注\n");
    printf("------------------------------------------------------------\n");
    
    while(p != NULL) {
        if(strcmp(p->data.category, category) == 0) {
            printRecord(p->data);
            found = 1;
        }
        p = p->next;
    }
    
    if(!found) {
        printf("未找到类别为 %s 的记录！\n", category);
    }
}

// 按金额范围查询
void queryByAmountRange(SLNode *head) {
    double minAmount, maxAmount;
    printf("请输入最小金额: ");
    scanf("%lf", &minAmount);
    printf("请输入最大金额: ");
    scanf("%lf", &maxAmount);
    
    SLNode *p = head->next;
    int found = 0;
    
    printf("查询结果：\n");
    printf("ID\t日期\t\t类型\t类别\t金额\t备注\n");
    printf("------------------------------------------------------------\n");
    
    while(p != NULL) {
        if(p->data.amount >= minAmount && p->data.amount <= maxAmount) {
            printRecord(p->data);
            found = 1;
        }
        p = p->next;
    }
    
    if(!found) {
        printf("未找到金额在 %.2lf 到 %.2lf 之间的记录！\n", minAmount, maxAmount);
    }
}

// 显示所有记录
void displayAll(SLNode *head) {
    if(ListLength(head) == 0) {
        printf("暂无记录！\n");
        return;
    }
    
    printf("所有账务记录（共%d条）：\n", ListLength(head));
    printf("ID\t日期\t\t类型\t类别\t金额\t备注\n");
    printf("------------------------------------------------------------\n");
    
    SLNode *p = head->next;
    while(p != NULL) {
        printRecord(p->data);
        p = p->next;
    }
}

// 统计功能
void statistics(SLNode *head) {
    double totalIncome = 0, totalExpense = 0;
    
    SLNode *p = head->next;
    while(p != NULL) {
        if(p->data.type == 0) {  // INCOME
            totalIncome += p->data.amount;
        } else {  // EXPENSE
            totalExpense += p->data.amount;
        }
        p = p->next;
    }
    
    double balance = totalIncome - totalExpense;
    
    printf("\n=== 财务统计 ===\n");
    printf("总收入: %.2lf\n", totalIncome);
    printf("总支出: %.2lf\n", totalExpense);
    printf("结余: %.2lf\n", balance);
    
    if(totalIncome > 0) {
        printf("支出占比: %.2lf%%\n", (totalExpense / totalIncome) * 100);
    }
}

// 按金额排序
void sortByAmount(SLNode *head, int ascending) {
    int length = ListLength(head);
    if(length == 0) {
        printf("暂无记录！\n");
        return;
    }
    
    int i, j;
    for(i = 0; i < length - 1; i++) {
        SLNode *p = head->next;
        for(j = 0; j < length - i - 1; j++) {
            SLNode *q = p->next;
            int shouldSwap = 0;
            
            if(ascending) {
                shouldSwap = (p->data.amount > q->data.amount);
            } else {
                shouldSwap = (p->data.amount < q->data.amount);
            }
            
            if(shouldSwap) {
                FinanceRecord temp = p->data;
                p->data = q->data;
                q->data = temp;
            }
            p = p->next;
        }
    }
    
    printf("排序完成！按金额%s序排列：\n", ascending ? "升" : "降");
    displayAll(head);
}

// 保存到文件
void saveToFile(SLNode *head, const char *filename) {
    FILE *file = fopen(filename, "w");
    if(file == NULL) {
        printf("无法打开文件 %s\n", filename);
        return;
    }
    
    fprintf(file, "ID,Date,Type,Category,Amount,Note\n");
    
    SLNode *p = head->next;
    while(p != NULL) {
        fprintf(file, "%ld,%s,%d,%s,%.2lf,%s\n",
                p->data.id,
                p->data.date,
                p->data.type,
                p->data.category,
                p->data.amount,
                p->data.note);
        p = p->next;
    }
    
    fclose(file);
    printf("数据已保存到 %s，共%d条记录\n", filename, ListLength(head));
}

// 从文件加载
void loadFromFile(SLNode *head, const char *filename) {
    FILE *file = fopen(filename, "r");
    if(file == NULL) {
        printf("无法打开文件 %s，可能是首次使用\n", filename);
        return;
    }
    
    char buffer[256];
    fgets(buffer, sizeof(buffer), file);
    
    int count = 0;
    while(fgets(buffer, sizeof(buffer), file) != NULL) {
        FinanceRecord record;
        int type;
        
        if(sscanf(buffer, "%ld,%10[^,],%d,%19[^,],%lf,%49[^\n]",
                  &record.id, record.date, &type, record.category, 
                  &record.amount, record.note) == 6) {
            record.type = type;
            ListInsert(head, ListLength(head), record);
            count++;
        }
    }
    
    fclose(file);
    printf("从 %s 加载了 %d 条记录\n", filename, count);
}